package controllers

import java.io.File
import java.nio.file.Files

import dao.{GroupDao, ModeDao}
import javax.inject.Inject
import play.api.data._
import play.api.data.Forms._
import play.api.mvc._
import utils.Utils
import play.api.data.format.Formats.doubleFormat
import tool.Tool


/**
  * Created by yz on 2018/5/23
  */
class Tool @Inject()(groupDao: GroupDao,modeDao: ModeDao) {

  def getUserId(implicit request: RequestHeader) = {
    request.session.get("id").get.toInt
  }

  def getProjectId(implicit request: RequestHeader) = {
    request.session.get("projectId").get.toInt
  }
  def getOptionProjectId(implicit request: RequestHeader) = {
    request.session.get("projectId")
  }

  def getUserIdDir(implicit request: RequestHeader) = {
    val userId = getUserId
    new File(Tool.dataDir, userId.toString)
  }

  def getProjectIdDir(projectId: Int)(implicit request: RequestHeader) = {
    val userIdDir = getUserIdDir
    new File(userIdDir, projectId.toString)
  }

  def getProjectIdDir(implicit request: RequestHeader) = {
    val projectId=getProjectId
    val userIdDir = getUserIdDir
    new File(userIdDir, projectId.toString)
  }

  case class ProjectIdData(projectId: Int)

  val projectIdForm = Form(
    mapping(
      "projectId" -> number
    )(ProjectIdData.apply)(ProjectIdData.unapply)
  )

  case class GeneIdData(geneId: String)

  val geneIdForm = Form(
    mapping(
      "geneId" -> text
    )(GeneIdData.apply)(GeneIdData.unapply)
  )

  def getDealFile(implicit request: RequestHeader) = {
    val projectIdDir=getProjectIdDir
    new File(projectIdDir, "deal.txt")
  }

  def getDbFile(implicit request: RequestHeader) = {
    val projectIdDir=getProjectIdDir
    new File(projectIdDir, "data.txt")
  }

  case class DataDealData(normal: Option[String], delete: Option[String], replace: Option[String])

  val dataDealForm = Form(
    mapping(
      "normal" -> optional(text),
      "delete" -> optional(text),
      "replace" -> optional(text)
    )(DataDealData.apply)(DataDealData.unapply)
  )

  case class DeleteData(iqr: Double)

  val deleteForm = Form(
    mapping(
      "iqr" -> of(doubleFormat)
    )(DeleteData.apply)(DeleteData.unapply)
  )

  case class ReplaceData(replaceMethod: String, rate: Double, assignValue: String, kValue: Int)

  val replaceForm = Form(
    mapping(
      "replaceMethod" -> text,
      "rate" -> of(doubleFormat),
      "assignValue" -> text,
      "kValue" -> number
    )(ReplaceData.apply)(ReplaceData.unapply)
  )

  case class NormalData(normalMethod: Option[Seq[Int]], colName: String, coefficient: Double)

  val normalForm = Form(
    mapping(
      "normalMethod" -> optional(seq(number)),
      "colName" -> text,
      "coefficient" -> of(doubleFormat)
    )(NormalData.apply)(NormalData.unapply)
  )

  case class GroupMessage(groupingName: String, groupNames: Seq[String],
                          sampleNames: Seq[String])

  val groupForm = Form(
    mapping(
      "groupingName" -> text,
      "groupNames" -> seq(text),
      "sampleNames" -> seq(text)
    )(GroupMessage.apply)(GroupMessage.unapply)
  )

  case class RelationData(id: Int, group1SampleNames: Seq[String], group2SampleNames: Seq[String])

  val relationForm = Form(
    mapping(
      "id" -> number,
      "group1SampleNames" -> seq(text),
      "group2SampleNames" -> seq(text)
    )(RelationData.apply)(RelationData.unapply)
  )

  case class DiffData(groupName: String)

  val diffForm = Form(
    mapping(
      "groupName" -> text
    )(DiffData.apply)(DiffData.unapply)
  )

  def productGroupFile(groupName: String, tmpDir: File)(implicit request: RequestHeader) = {
    val projectId = getProjectId
    val group = Utils.execFuture(groupDao.selectByGroupName(projectId, groupName)).get
    Utils.productGroupFile(tmpDir, group.content)
  }

  case class GroupData(groupName: String)

  val groupNameForm = Form(
    mapping(
      "groupName" -> text
    )(GroupData.apply)(GroupData.unapply)
  )

  case class TTestData(groupName: String, paired: String, pCutoff: String, qCutoff: String, method: String,
                       logCutoff: String, varEqual: String)

  val tTestForm = Form(
    mapping(
      "groupName" -> text,
      "paired" -> text,
      "pCutoff" -> text,
      "qCutoff" -> text,
      "method" -> text,
      "logCutoff" -> text,
      "varEqual" -> text
    )(TTestData.apply)(TTestData.unapply)
  )

  case class GoBarData(terms: Seq[String], datas: Seq[String], kinds: Seq[String])

  val goBarForm = Form(
    mapping(
      "terms" -> seq(text),
      "datas" -> seq(text),
      "kinds" -> seq(text)
    )(GoBarData.apply)(GoBarData.unapply)
  )

  case class BarData(terms: Seq[String], datas: Seq[String])

  val barForm = Form(
    mapping(
      "terms" -> seq(text),
      "datas" -> seq(text)
    )(BarData.apply)(BarData.unapply)
  )

  case class GoEnrichData(geneId: String, twa: String, ewa: String)

  val goEnrichForm = Form(
    mapping(
      "geneId" -> text,
      "twa" -> text,
      "ewa" -> text
    )(GoEnrichData.apply)(GoEnrichData.unapply)
  )

  case class KeggEnrichData(geneId: String, method: String, fdr: String, cutoff: String, pValue: String)

  val keggEnrichForm = Form(
    mapping(
      "geneId" -> text,
      "method" -> text,
      "fdr" -> text,
      "cutoff" -> text,
      "pValue" -> text
    )(KeggEnrichData.apply)(KeggEnrichData.unapply)
  )

  case class HeatmapData(method: String, rowDist: String, colDist: String, rowCluster: String, colCluster: String)

  val heatmapForm = Form(
    mapping(
      "method" -> text,
      "rowDist" -> text,
      "colDist" -> text,
      "rowCluster" -> text,
      "colCluster" -> text
    )(HeatmapData.apply)(HeatmapData.unapply)
  )

  case class SampleNamesData(sampleNames: Seq[String])

  val sampleNamesForm = Form(
    mapping(
      "sampleNames" -> seq(text)
    )(SampleNamesData.apply)(SampleNamesData.unapply)
  )

  case class PcaData(method: String, sampleName: Seq[String], groupName: String, dtMethod: String, x: String, y: String)

  val pcaForm = Form(
    mapping(
      "method" -> text,
      "sampleName" -> seq(text),
      "groupName" -> text,
      "dtMethod" -> text,
      "x" -> text,
      "y" -> text
    )(PcaData.apply)(PcaData.unapply)
  )

  case class HClusterData(method: String, sampleDist: String, sampleCluster: String)

  val hClusterForm = Form(
    mapping(
      "method" -> text,
      "sampleDist" -> text,
      "sampleCluster" -> text
    )(HClusterData.apply)(HClusterData.unapply)
  )

  val groupingNameFom = Form(
    single(
      "groupingName" -> text
    )
  )

  case class RocData(groupingName: String, pGroup: String)

  val rocForm = Form(
    mapping(
      "groupingName" -> text,
      "pGroup" -> text
    )(RocData.apply)(RocData.unapply)
  )

  def getRequestDomain(implicit request: RequestHeader)={
    request.domain
  }

  def getUserIdDir(userId:Int)={
    new File(Tool.dataDir,userId.toString)

  }

}
